<!-- 上传试题 -->
<script lang="ts">
export declare interface SubjectType {
  isEnabled?: number;
  ownerType?: number;
  subjectId?: string;
  title?: string;
  [propName: string]: any
}
</script>
<script setup lang='ts'>
import { reactive, ref, onMounted } from 'vue'
import { useCurrentInstance } from '@/common/utils/methods'
import { ResponseType } from '@/common/types/response';
import type { UploadFile } from 'element-plus/es/components/upload/src/upload.type'
import type { ElForm } from 'element-plus'
const { $message, $axios, branchId, brandId } = useCurrentInstance();
type FormInstance = InstanceType<typeof ElForm>

const props = defineProps<{
  subjectList: Array<SubjectType>
}>()


const data = reactive({
  uploadDialog: false,
  status: 0, // 上传状态上
  percentage: 0,
  result: {} as ResponseType,
  taskId: '',
})

const showUploadDialog = () => {
  data.uploadDialog = true;
}

const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
  subjectId: '',
  file: {} as UploadFile
})

const validateFile = (rule: any, value: any, callback: any) => {
  if (!ruleForm.file.raw) {
    callback(new Error('请选择导入文件'))
  } else {
    callback()
  }
}
const rules = reactive({
  subjectId: [
    {
      required: true,
      message: '请选择科目',
      trigger: 'change',
    },
  ],
  file: [
    {
      required: true,
      validator: validateFile,
      trigger: 'change'
    }
  ]
})

const upload = ref();
const fileChange = (file: UploadFile) => {
  if (file.raw.size / 1024 / 1024 > 3) {
    upload.value.clearFiles()
    $message.error('导入文件不能超过3M');
  } else {
    ruleForm.file = file
  }
}

const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      let formData = new FormData()
      formData.append('brandId', brandId)
      formData.append('branchId', branchId)
      formData.append('subjectId', ruleForm.subjectId)
      formData.append('file', ruleForm.file.raw)
      $axios.post('/training.exam.api/question/import', formData, {
        timeout: 10 * 60 * 10000,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then((res: ResponseType) => {
        if (res.code === '200') {
          const { taskId, status } = res.data
          data.taskId = taskId
          if (!status) {
            $message.warning('导入失败')
          } else {
            data.status = 1
            getUploadStatus()
          }
        }
      })
    } else {
      return false
    }
  })
}

// 重置上传组件，以及各种状态
const reset = () => {
  data.uploadDialog = false;
  ruleForm.file = {} as UploadFile;
  ruleFormRef.value?.resetFields()
}

let timer: NodeJS.Timer;
const getUploadStatus = () => {
  try {
    timer = setInterval(async () => {
      let formData = new FormData()
      formData.append('taskId', data.taskId)
      let res = await $axios.post('/training.exam.api/question/import/result', formData)
      data.result = res.data
      const { success = 0, total = 0, failed = 0 } = res.data
      data.percentage = Math.floor(((success + failed) * 100) / total)
      if (res.data.status) {
        data.status = 2

        if (data.status === 2) {
          clearInterval(timer);
        }
      }
    }, 3000)
  } catch (e) {
    if (timer) {
      clearInterval(timer);
    }
    return false
  }
}

// 下载失败文件
const downloadFile = () => {
  $axios({
    url: '/training.exam.api/question/import/resultfile?taskId=' + data.taskId,
    method: 'get',
    responseType: 'blob',
    timeout: 10 * 60 * 1000,
    headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  }).then((res: Blob) => {
    let url = window.URL.createObjectURL(new Blob([res]))
    let link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.setAttribute('download', '导入失败试题.xlsx')
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  })
}

defineExpose({ showUploadDialog })
</script>

<template>
  <el-dialog v-model="data.uploadDialog" title="导入题目" width="550px" :before-close="reset">
    <div v-if="data.status === 0">
      <div class="upload-tip">*请按照导题模板文件规定的题目格式进行导入</div>
      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px">
        <el-form-item label="导入科目：" prop="subjectId">
          <el-select v-model="ruleForm.subjectId" placeholder="请选择科目">
            <el-option
              :label="subject.label"
              :value="subject.value"
              v-for="subject in subjectList"
              :key="subject.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="导入文件：" prop="file">
          <el-upload
            ref="upload"
            :on-change="fileChange"
            action="''"
            :auto-upload="false"
            :limit="1"
            accept=".xlsx"
          >
            <el-button slot="trigger" type="primary">选取文件</el-button>
            <div slot="tip" class="el-upload__tip">
              仅支持.xlsx文件，大小不超过3M（
              <a
                class="_key_color"
                href="/exam/demo/导入题库excel模板.xlsx"
                download="导入题库excel模板"
              >Excel模板</a>
              )
            </div>
          </el-upload>
        </el-form-item>
      </el-form>
    </div>

    <div v-else>
      <div class="center mb20">{{ data.status == 1 ? '导入中···' : '导入完成' }}</div>
      <el-progress
        :text-inside="true"
        :stroke-width="24"
        :percentage="data.percentage"
        :show-text="false"
      ></el-progress>
      <div v-if="data.percentage < 100">{{ data.percentage }}%</div>
      <div class="center mt20" v-else>
        导入成功
        <span style="color: green">{{ data.result.success }}</span>
        题 ，导入失败
        <span style="color: red">{{ data.result.failed }}</span>
        题
        <template v-if="data.result.failed > 0">
          ,
          <el-button type="text" @click="downloadFile">查看失败试题</el-button>
        </template>
      </div>
    </div>

    <template #footer>
      <span class="dialog-footer" v-if="data.status === 0">
        <el-button @click="reset">取消</el-button>
        <el-button type="primary" @click="submitForm(ruleFormRef)">导入</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.upload-tip {
  color: #3d88f2;
  line-height: 20px;
  text-align: center;
  padding: 8px 20px;
  background: rgba(61, 136, 242, 0.2);
  border-radius: 6px;
  margin-bottom: 20px;
}
:deep(.el-upload) {
  text-align: left;
}
.center {
  text-align: center;
}
.mb20 {
  margin-bottom: 20px;
}
.mt20 {
  margin-top: 20px;
}
</style>